package com.vhr.service.impl;

import com.vhr.VO.SalaryCountVO;
import com.vhr.VO.SalaryVO;
import com.vhr.entities.*;
import com.vhr.mapper.EmployeeMapper;
import com.vhr.mapper.SalaryMapper;
import com.vhr.mapper.WelfareMapper;
import com.vhr.service.ICheckService;
import com.vhr.service.IEmployeeService;
import com.vhr.service.ILeaveService;
import com.vhr.service.ISalaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ISalaryServiceImpl implements ISalaryService{

    @Autowired
    private SalaryMapper salaryMapper;

    @Autowired
    private ILeaveService iLeaveService;

    @Autowired
    private ICheckService iCheckService;

    @Autowired
    private IEmployeeService iEmployeeService;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private WelfareMapper welfareMapper;

    //计算月份薪酬
    @Override
    public double calculatePersonSalary(Employee emp,Integer month,Integer year) {
        //加钱项
        double monthBonus = calculateMonthBonus(emp,month,year);
        double overTime = calculateOvertimeSalary(emp,month,year);
        double basic = iEmployeeService.selectContractByEmployee(emp).getBaseSalary();
        double food = LookFoodSalary(emp);
        double travel = LookTravelSalary(emp);
        double house = LookTravelSalary(emp);
        //减钱项
        double leave = calculateLeaveFine(emp,month,year);
        double check = calculateCheck(emp,month,year);
        double salary = monthBonus+overTime+basic+food+travel+house-leave-check;
        double tax = calculateTax(salary,emp,month,year);

        System.out.println("月"+monthBonus+",加"+overTime+",基"+basic+",食物"+food+",出行"+travel+",住"+house+",请"+leave+",考"+check+",税"+tax);
        //实发工资
        double realSalary = salary-tax;

        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);

        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(emp.getEmpId());
        List<Salary> list = salaryMapper.selectByExample(salaryExample);

        Salary select_salary = list.get(0);
        select_salary.setRealSalary(realSalary);

        salaryMapper.updateByExampleSelective(select_salary,salaryExample);

        return realSalary;
    }

    //查询员工的月奖金,思路：查询出来当月奖金
    @Override
    public double calculateMonthBonus(Employee emp,Integer month,Integer year) {

        //通过criteria构造查询条件
        SalaryExample salaryExample = new SalaryExample();
        //去除重复,true是选择不重复记录,false反之
        salaryExample.setDistinct(false);
        //构造自定义查询条件
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);
        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(emp.getEmpId());
        //criteria.andEmpIdEqualTo(emp.getEmpId());
        List<Salary> list = salaryMapper.selectByExample(salaryExample);
        System.out.println(list.get(0));

        //自定义查询条件可能返回多条记录,使用List接收
        //获取salary
        Salary salary = list.get(0);
        System.out.println(salary);
        //返回月奖金
        return salary.getMonthBonus();
    }

    //计算加班补贴，思路：查出加班时长，算出加班费，将加班费插入salary表，返回加班补贴
    @Override
    public double calculateOvertimeSalary(Employee emp,Integer month,Integer year) {
        /**
         * 查出加班时长
         * */
        double time = 0;
        String date = "";
        if(month>=10 && month <=12){
            date = year+"-"+month;
        }else{
            date = year+"-0"+month;
        }
        List<Check> list = iCheckService.countOverTimeByCheck(emp.getEmpId(), date, 5);
        for (int i =0;i< list.size();i++){
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(list.get(i).getSgininTime());

            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTime(list.get(i).getSignbackTime());

            long start = calendar1.getTimeInMillis();
            long end = calendar2.getTimeInMillis();

            time= (end - start)/1000/60/60 + time; //小时
        }
        //按每小时12元来算总工资
        double overtime_salary = time * 12;

        /*将加班费插入到salary中*/
        //根据emp的id查出所在的salary记录
        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);

        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(emp.getEmpId());
        List<Salary> list_salary = salaryMapper.selectByExample(salaryExample);
        Salary salaryByEmpId = list_salary.get(0);
        //根据salaryId将加班补贴更新到salary中
        Salary salary = new Salary();
        salary.setEmpId(emp.getEmpId());
        salary.setSalaryId(salaryByEmpId.getSalaryId());
        salary.setOvertimeSalary(overtime_salary);
        int i = salaryMapper.updateByExampleSelective(salary,salaryExample);
        if(i>0){
            System.out.println("加班费插入salary表成功");
        }
        //返回加班补贴
        return overtime_salary;
    }

    //计算请假扣款
    @Override
    public double calculateLeaveFine(Employee emp,Integer month,Integer year) {
        /**
         * 查出请假扣款时长
         * */
        //调用请假扣款查询
        List<Leave> list = iLeaveService.selectByEmployee(emp);
        //遍历计算总时长
        int time = 0;
        for (int i =0;i< list.size();i++){
            //System.out.println("请假时间："+list.get(i).getLeaveStart().getMonth()+1);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(list.get(i).getLeaveStart());
            int tyear = calendar.get(Calendar.YEAR);
            int tmonth = calendar.get(calendar.MONTH)+1;

            if((tyear==year)&&(tmonth==month)&&list.get(i).getEmpId()==emp.getEmpId()){
                time = time + list.get(i).getLeaveDuration();
            }
        }
        //按每小时34元来算总工资
        double leave_salary = time * 34;

        System.out.println(leave_salary);
        /*将请假费插入到salary中*/
        //根据emp的id和月份查出所在的salary记录
        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);

        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(emp.getEmpId());
        List<Salary> list_salary = salaryMapper.selectByExample(salaryExample);
        Salary salaryByEmpId = list_salary.get(0);
        //根据salaryId将请假的钱更新到salary中
        Salary salary = new Salary();
        salary.setEmpId(emp.getEmpId());
        salary.setSalaryId(salaryByEmpId.getSalaryId());
        salary.setLeaveFine(leave_salary);
        int i = salaryMapper.updateByExampleSelective(salary,salaryExample);
        if(i>0){
            System.out.println("请假费插入salary表成功");
        }
        //返回
        return leave_salary;
    }

    //计算考勤迟到，旷工，早退，那些扣款，存到illegal_fine
    @Override
    public double calculateCheck(Employee emp,Integer month,Integer year) {
        List<Check> list = iCheckService.selectPersonCheck(emp);
        //迟到，旷工，早退的次数,分别对着1,3,4
        int time_late = 0;
        int time_dismiss = 0;
        int time_before = 0;
        for (int i =0;i< list.size();i++){
            //System.out.println("考勤月："+list.get(i).getSgininTime().getMonth()+1);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(list.get(i).getCurrentDate());
            int tyear = calendar.get(Calendar.YEAR);
            int tmonth = calendar.get(calendar.MONTH)+1;

            if((tyear==year)&&(tmonth==month)&&list.get(i).getEmpId()==emp.getEmpId()){
                if(list.get(i).getCheckStatus()==1){
                    time_late = time_late+1;
                }
                if(list.get(i).getCheckStatus()==3){
                    time_dismiss = time_dismiss + 1;
                }
                if (list.get(i).getCheckStatus()==4){
                    time_before = time_before +1;
                }
            }
        }
        //分别算出迟到，旷工，早退的钱数
        double time_late_salary = time_late * 10;//迟到每次扣10元
        double time_dismiss_salary = time_dismiss * 100; //旷工每次扣100元
        double time_before_salary = time_before *20; //早退每次扣20元
        //计算总的数
        double illegal_fine = time_late_salary + time_dismiss_salary + time_before_salary;

        /*将迟到，旷工，早退的钱数插入到salary中*/
        //根据emp的id查出所在的salary记录
        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);

        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(emp.getEmpId());
        List<Salary> list_salary = salaryMapper.selectByExample(salaryExample);
        Salary salaryByEmpId = list_salary.get(0);
        //根据salaryId将迟到，旷工，早退的钱数更新到salary中
        Salary salary = new Salary();
        salary.setEmpId(emp.getEmpId());
        salary.setSalaryId(salaryByEmpId.getSalaryId());
        salary.setIllegalFine(illegal_fine);
        //动态地将内容插入进去，原来有的东西不会被清空
        int i = salaryMapper.updateByExampleSelective(salary,salaryExample);
        if(i>0){
            System.out.println("请迟到，旷工，早退的钱插入salary表成功");
        }

        return illegal_fine;
    }

    //更改补贴方式，大于0是成功，0是失败
    @Override
    public int updateWelfare(Employee emp, Integer id) {

        emp.setWelfateId(id);
        int i = employeeMapper.updateByPrimaryKeySelective(emp);

        if(i>0){
            System.out.println("修改员工补贴成功");
            return i;
        }
        return 0;
    }

    /*查看员工的伙食补贴*/
    @Override
    public double LookFoodSalary(Employee employee) {
        //查出员工
        Employee emp = employeeMapper.selectByPrimaryKey(employee.getEmpId());
        //查出补贴方式
        Welfare welfare = welfareMapper.selectByPrimaryKey(emp.getWelfateId());
        Double foodSalary = welfare.getFoodSalary();
        return foodSalary;
    }

    /*查看员工的出行补贴*/
    @Override
    public double LookTravelSalary(Employee employee) {
        //查出员工
        Employee emp = employeeMapper.selectByPrimaryKey(employee.getEmpId());
        //查出补贴方式
        Welfare welfare = welfareMapper.selectByPrimaryKey(emp.getWelfateId());
        Double travelSalary = welfare.getTravelSalary();
        return travelSalary;
    }

    /*查看员工的住房补贴*/
    @Override
    public double LookHouseSalary(Employee employee) {
        //查出员工
        Employee emp = employeeMapper.selectByPrimaryKey(employee.getEmpId());
        //查出补贴方式
        Welfare welfare = welfareMapper.selectByPrimaryKey(emp.getWelfateId());
        Double houseSalary = welfare.getHouseSalary();
        return houseSalary;
    }

    //计算扣税
    @Override
    public double calculateTax(Double salary,Employee employee,Integer month,Integer year) {
        /*
    * 0-5000:不扣
    * 5000-8000：扣3％
    * 8000-17000：扣10％
    * >17000:扣20％
    * */
        double tax = 0;
        if(salary<=5000){
            tax = 0;
        }else if(salary>=5001&&salary<=8000){
            tax = (salary-5001)*0.03;
        }else if(salary>=8001&&salary<=17000){
            tax = 3000*0.03+(salary-8000)*0.1;
        }else{
            tax = 3000*0.03+9000*0.1+(salary-17000)*0.2;
        }

        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();

        Calendar start = Calendar.getInstance();
        start.set(year,month-1,1,0,0,0);
        Calendar end = Calendar.getInstance();
        end.set(year, month,1,0,0,0);

        criteria.andPayTimeBetween(start.getTime(),end.getTime()).andEmpIdEqualTo(employee.getEmpId());
        List<Salary> list_salary = salaryMapper.selectByExample(salaryExample);
        Salary salaryByEmpId = list_salary.get(0);

        Salary s = new Salary();
        s.setEmpId(employee.getEmpId());
        s.setSalaryId(salaryByEmpId.getSalaryId());
        s.setTax(tax);
        //动态地将内容插入进去，原来有的东西不会被清空
        int i = salaryMapper.updateByExampleSelective(s,salaryExample);
        if(i>0){
            System.out.println("计算tax的钱插入salary表成功");
        }
        return tax;
    }

    /*国泰：统计薪资信息,date表示某个月份*/
    @Override
    public List<SalaryCountVO> countBySalary(Date date) {
        List<SalaryCountVO> salaryCountVOList = new ArrayList<SalaryCountVO>();
        List<Integer> resultList = new ArrayList<Integer>();

        SalaryExample salaryExample = new SalaryExample();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        Date left = cal.getTime();
        cal.add(Calendar.MONTH,+1);
        Date right = cal.getTime();

        Double[] sum = {3000.00,5000.00,8000.00,12000.00,20000.00};
        String[] salaryStage = {"3000以下","3000-5000","5000-8000","8000-12000","12000-20000","20000以上"};
        SalaryExample.Criteria criteria = salaryExample.createCriteria();
        criteria.andRealSalaryLessThan(3000.00).andPayTimeBetween(left,right);
        //3000以下人数
        SalaryCountVO salaryCountVO1 = new SalaryCountVO(salaryStage[0],salaryMapper.countByExample(salaryExample));
        salaryCountVOList.add(salaryCountVO1);

        Integer count=1;
        salaryExample.clear();
        //3000-5000,5000-8000,8000-12000,12000-20000,人数
        for(int i=0;i<sum.length-1;i++){
            SalaryExample.Criteria criteria2 = salaryExample.createCriteria();
            criteria2.andPayTimeBetween(left,right).andRealSalaryBetween(sum[i],sum[i+1]);
            SalaryCountVO salaryCountVO2 = new SalaryCountVO(salaryStage[count],salaryMapper.countByExample(salaryExample));
            count++;
            salaryCountVOList.add(salaryCountVO2);
            salaryExample.clear();
        }
        salaryExample.clear();
        SalaryExample.Criteria criteria3 = salaryExample.createCriteria();
        //20000以上人数
        criteria3.andRealSalaryGreaterThan(20000.00).andPayTimeBetween(left,right);

        SalaryCountVO salaryCountVO3 = new SalaryCountVO(salaryStage[salaryStage.length-1],salaryMapper.countByExample(salaryExample));
        salaryCountVOList.add(salaryCountVO3);

        return salaryCountVOList;
    }


    /*查询所有员工的所有的工资单*/
    @Override
    public List<SalaryToPageAdmin> selectAllEmpSalary() {

        List<SalaryToPageAdmin> salaryToPageAdmins = new ArrayList<>();

        List<Salary> list = salaryMapper.selectByExample(null);

        for(int i=0;i<list.size();i++){
            SalaryToPageAdmin salaryToPageAdmin = new SalaryToPageAdmin();
            //时间：年月
            Date date = list.get(i).getPayTime();
            DateFormat dateFormat= new SimpleDateFormat("yyyy-MM");
            String time = dateFormat.format(date);
            salaryToPageAdmin.setDate(time);
            //id
            salaryToPageAdmin.setId(list.get(i).getSalaryId());
            //基本工资
            Employee employee = new Employee();
            employee.setEmpId(list.get(i).getEmpId());
            salaryToPageAdmin.setBasic( iEmployeeService.selectContractByEmployee(employee).getBaseSalary());
            //月奖
            salaryToPageAdmin.setMonthBonus(list.get(i).getMonthBonus());
            //加班补贴
            salaryToPageAdmin.setOverTime(list.get(i).getOvertimeSalary());
            //食物补贴
            Integer welfateId = iEmployeeService.selectEmployeeByPrimaryKey(employee).getWelfateId();
            salaryToPageAdmin.setFood(welfareMapper.selectByPrimaryKey(welfateId).getFoodSalary());
            //出行补贴
            salaryToPageAdmin.setTravel(welfareMapper.selectByPrimaryKey(welfateId).getTravelSalary());
            //住房补贴
            salaryToPageAdmin.setHouse(welfareMapper.selectByPrimaryKey(welfateId).getHouseSalary());
            //违规扣钱+请假扣钱:check
            salaryToPageAdmin.setCheck(list.get(i).getIllegalFine()+list.get(i).getLeaveFine());
            //个税
            salaryToPageAdmin.setTex(list.get(i).getTax());
            //真实工资
            salaryToPageAdmin.setReal_salary(list.get(i).getRealSalary());
            //加钱项：
            double monthBonus = list.get(i).getMonthBonus();
            double overTime = list.get(i).getOvertimeSalary();
            double food = welfareMapper.selectByPrimaryKey(welfateId).getFoodSalary();
            double travel = welfareMapper.selectByPrimaryKey(welfateId).getTravelSalary();
            double house = welfareMapper.selectByPrimaryKey(welfateId).getHouseSalary();
            salaryToPageAdmin.setAward(monthBonus+overTime+food+travel+house);
            //减钱项：
            double check = list.get(i).getIllegalFine()+list.get(i).getLeaveFine();
            double tax = list.get(i).getTax();
            salaryToPageAdmin.setTakeOut(check+tax);
            //编号：
            salaryToPageAdmin.setEmpNumber(iEmployeeService.selectByEmployee(employee).getEmpNum());
            //姓名：
            salaryToPageAdmin.setEmpName(iEmployeeService.selectEmployeeByPrimaryKey(employee).getEmpName());
            //将工资条加入到集合中去
            salaryToPageAdmins.add(salaryToPageAdmin);
        }
        return salaryToPageAdmins;
    }

    /*查询单个员工不同月的所有的工资单*/
    @Override
    public List<SalaryToPage> selectOneEmpSalary(Employee employee) {
        //构造查询条件
        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();
        //根据员工查询，返回一个list
        criteria.andEmpIdEqualTo(employee.getEmpId());

        List<Salary> list = salaryMapper.selectByExample(salaryExample);

        System.out.println(list.size()+"--------------------------------");

        //定义一个工资的扩展类
        List<SalaryToPage> salaryEmpVOList = new ArrayList<>();
        //填充扩展类
        for(int i=0;i<list.size();i++){
            SalaryToPage salaryEmpVO = new SalaryToPage();
            //时间：年月
            Date date = list.get(i).getPayTime();
            DateFormat dateFormat= new SimpleDateFormat("yyyy-MM");
            String time = dateFormat.format(date);
            salaryEmpVO.setDate(time);
            //id
            salaryEmpVO.setId(list.get(i).getSalaryId());
            //基本工资
            salaryEmpVO.setBasic( iEmployeeService.selectContractByEmployee(employee).getBaseSalary());
            //月奖
            salaryEmpVO.setMonthBonus(list.get(i).getMonthBonus());
            //加班补贴
            salaryEmpVO.setOverTime(list.get(i).getOvertimeSalary());
            //食物补贴
            Integer welfateId = iEmployeeService.selectEmployeeByPrimaryKey(employee).getWelfateId();
            salaryEmpVO.setFood(welfareMapper.selectByPrimaryKey(welfateId).getFoodSalary());
            //出行补贴
            salaryEmpVO.setTravel(welfareMapper.selectByPrimaryKey(welfateId).getTravelSalary());
            //住房补贴
            salaryEmpVO.setHouse(welfareMapper.selectByPrimaryKey(welfateId).getHouseSalary());
            //违规扣钱
            salaryEmpVO.setCheck(list.get(i).getIllegalFine());
            //请假扣钱
            salaryEmpVO.setLeave(list.get(i).getLeaveFine());
            //个税
            salaryEmpVO.setTex(list.get(i).getTax());
            //真实工资
            salaryEmpVO.setReal_salary(list.get(i).getRealSalary());
            //将工资条加入到集合中去
            salaryEmpVOList.add(salaryEmpVO);
        }
        return salaryEmpVOList;
    }

    @Override
    /*查询单个员工不同月的所有的工资单：原始数据*/
    public List<Salary> selectByEmpIdSalary(Employee employee) {
        SalaryExample salaryExample = new SalaryExample();
        salaryExample.setDistinct(false);
        SalaryExample.Criteria criteria = salaryExample.createCriteria();
        //根据员工查询，返回一个list
        criteria.andEmpIdEqualTo(employee.getEmpId());

        List<Salary> list = salaryMapper.selectByExample(salaryExample);
        return list;
    }

    @Override
    public List<SalaryVO> selectSomeBodyByNameAndTimeAndDept(String empName, Integer deptId, String payTime) {
        return salaryMapper.selectSomeBodyByNameAndTimeAndDept(empName, deptId, payTime);
    }

    /*计算月工资,很高的效率*/
    @Override
    public void countPersonSalary(Employee emp, Integer month, Integer year) {
        String date = "";
        if(month>9){
            date=year+"-"+month;
        }else {
            date=year+"-0"+month;
        }
        Map map = salaryMapper.countPersonSalary(emp.getEmpId(), date);
        System.out.println(map.toString());
    }

    @Override
    /*查询所有员工的所有的工资单:原始数据*/
    public List<Salary> selectAllSalary() {
        List<Salary> list = salaryMapper.selectByExample(null);
        return list;
    }
}
